#include "Sphere.hpp"

std::optional<ShadePayload> Sphere::hit(const Ray& ray)const {
    std::optional<ShadePayload> payload;
    float a = 1;
    float b = 2 * (ray.direction().dot(ray.origin() - pos));
    float c = ray.origin().dot(ray.origin()) - 2 * pos.dot(ray.origin()) + pos.dot(pos) - radius * radius;
    float delta = b * b - 4 * a * c;
    if (delta >= 0) {
        float t1 = (-b - sqrt(delta)) / (2 * a);
        float t2 = (-b + sqrt(delta)) / (2 * a);
        payload.emplace();
        payload->mat = this->mat;
        if (t1 >= epsilon && t2 >= epsilon) {
            payload->tNear = t1;
            payload->normal = (ray.at(payload->tNear) - pos).normalized();
            payload->pos = ray.at(t1);
            payload->isFrontFace = true;
            // payload->color = (payload->normal + Eigen::Vector3f(1, 1, 1)) / 2;
        }
        else if (t1 < 0 && t2 >= epsilon) {
            payload->tNear = t2;
            payload->normal = (pos - ray.at(payload->tNear)).normalized();
            payload->pos = ray.at(t2);
            payload->isFrontFace = false;
            // payload->color = (payload->normal + Eigen::Vector3f(1, 1, 1)) / 2;
        }
        else {
            payload.reset();
        }
    }

    return payload;
}